package com.rickpan.service;

import com.rickpan.dto.siliconflow.SiliconFlowRequest;
import com.rickpan.dto.siliconflow.SiliconFlowImageRequest;
import com.rickpan.dto.request.ApiKeyRequest;
import com.rickpan.dto.request.ChatRequest;
import com.rickpan.dto.response.ApiKeyResponse;
import com.rickpan.dto.response.ImageGenerationResponse;
import com.rickpan.dto.response.TestApiKeyResponse;
import com.rickpan.entity.UserApiKey;
import com.rickpan.exception.BusinessException;
import com.rickpan.repository.UserApiKeyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * AI聊天服务
 */
@Service
public class AIChatService {

    private static final Logger log = LoggerFactory.getLogger(AIChatService.class);

    @Autowired
    private UserApiKeyRepository userApiKeyRepository;
    
    @Autowired
    private SiliconFlowClient siliconFlowClient;

    @Autowired
    private SiliconFlowImageClient siliconFlowImageClient;

    @Autowired
    private RedisService redisService;

    /**
     * 发送消息并流式返回响应
     * @param userId 用户ID
     * @param request 聊天请求
     * @param outputStream 输出流
     */
    public void sendMessageStream(Long userId, ChatRequest request, OutputStream outputStream) throws IOException {
        try {
            // 获取用户API Key
            UserApiKey userApiKey = getUserApiKey(userId);
            if (userApiKey == null) {
                String errorMsg = "data: {\"error\":\"API Key not configured\"}\n\n";
                outputStream.write(errorMsg.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                return;
            }

            // 检查是否为图片生成请求
            if (Boolean.TRUE.equals(request.getIsImageGeneration())) {
                handleImageGeneration(userId, request, outputStream, userApiKey);
                return;
            }

            // 检查是否为图片理解请求
            if (Boolean.TRUE.equals(request.getIsImageUnderstanding())) {
                handleImageUnderstanding(userId, request, outputStream, userApiKey);
                return;
            }

            // 构建硅基流动AI请求（文本聊天）
            // 对于文本聊天，始终使用用户配置的聊天模型，忽略请求中可能的图片模型
            String chatModel = userApiKey.getModel();

            // 确保使用的是有效的聊天模型，如果是图片模型则使用默认聊天模型
            if ("Kwai-Kolors/Kolors".equals(chatModel)) {
                chatModel = "THUDM/GLM-4.1V-9B-Thinking"; // 默认聊天模型
                log.warn("User {} has image model as default, using default chat model instead", userId);
            }

            SiliconFlowRequest siliconFlowRequest = SiliconFlowRequest.builder()
                    .model(chatModel)
                    .temperature(0.8)
                    .topP(0.8)
                    .stream(true)  // 改为true，启用真正的流式
                    .addUserMessage(request.getMessage())
                    .build();

            log.info("Sending streaming message to SiliconFlow for user {}, model: {}", userId, siliconFlowRequest.getModel());

            // 调用硅基流动AI流式API
            siliconFlowClient.sendStreamRequest(userApiKey.getApiKey(), siliconFlowRequest, outputStream);

            log.info("Message stream completed for user {}", userId);

        } catch (Exception e) {
            log.error("Error in sendMessageStream for user {}: {}", userId, e.getMessage(), e);
            try {
                String errorMsg = "data: {\"error\":\"" + e.getMessage() + "\"}\n\n";
                outputStream.write(errorMsg.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
            } catch (IOException ioException) {
                log.error("Failed to write final error message: {}", ioException.getMessage());
            }
        }
    }

    /**
     * 保存用户API Key
     * @param userId 用户ID
     * @param request API Key请求
     */
    @Transactional
    public void saveApiKey(Long userId, ApiKeyRequest request) {
        UserApiKey userApiKey = userApiKeyRepository.findByUserId(userId)
                .orElse(new UserApiKey());
        
        userApiKey.setUserId(userId);
        userApiKey.setApiKey(request.getApiKey()); // 注意：实际应用中需要加密
        userApiKey.setModel(request.getModel());
        userApiKey.setIsActive(true);
        
        if (userApiKey.getId() == null) {
            // 新建记录，设置创建时间
            userApiKey.setCreatedAt(LocalDateTime.now());
        }
        userApiKey.setUpdatedAt(LocalDateTime.now());
        
        userApiKeyRepository.save(userApiKey);
        
        // 清除缓存
        String cacheKey = "user_api_key:" + userId;
        redisService.del(cacheKey);
        
        log.info("API Key saved for user {}", userId);
    }

    /**
     * 获取用户API Key配置
     * @param userId 用户ID
     * @return API Key配置响应
     */
    public ApiKeyResponse getApiKey(Long userId) {
        UserApiKey userApiKey = getUserApiKey(userId);
        if (userApiKey == null) {
            return ApiKeyResponse.builder()
                    .hasApiKey(false)
                    .build();
        }
        
        return ApiKeyResponse.builder()
                .hasApiKey(true)
                .model(userApiKey.getModel())
                .maskedApiKey(userApiKey.getApiKey()) // 返回原始API Key，不掩码
                .build();
    }

    /**
     * 测试API Key是否有效
     * @param userId 用户ID
     * @return 测试结果
     */
    public TestApiKeyResponse testApiKey(Long userId) {
        UserApiKey userApiKey = getUserApiKey(userId);
        if (userApiKey == null) {
            throw new BusinessException("API Key not configured");
        }

        try {
            boolean isValid = siliconFlowClient.testApiKey(userApiKey.getApiKey());
            return TestApiKeyResponse.builder()
                    .valid(isValid)
                    .message(isValid ? "API Key is valid" : "API Key is invalid")
                    .build();
        } catch (Exception e) {
            log.error("API Key test failed for user {}: {}", userId, e.getMessage());
            return TestApiKeyResponse.builder()
                    .valid(false)
                    .message("Test failed: " + e.getMessage())
                    .build();
        }
    }

    /**
     * 获取用户API Key（带缓存）
     * @param userId 用户ID
     * @return 用户API Key
     */
    private UserApiKey getUserApiKey(Long userId) {
        // 先从缓存获取
        String cacheKey = "user_api_key:" + userId;
        try {
            Object cached = redisService.get(cacheKey);
            if (cached instanceof UserApiKey) {
                return (UserApiKey) cached;
            }
        } catch (Exception e) {
            log.warn("Failed to get API key from cache: {}", e.getMessage());
        }

        // 从数据库获取
        Optional<UserApiKey> optional = userApiKeyRepository.findActiveByUserId(userId);
        if (optional.isPresent()) {
            UserApiKey userApiKey = optional.get();
            try {
                // 创建一个简化的对象用于缓存，避免Hibernate代理问题
                UserApiKey cacheableApiKey = new UserApiKey();
                cacheableApiKey.setId(userApiKey.getId());
                cacheableApiKey.setUserId(userApiKey.getUserId());
                cacheableApiKey.setApiKey(userApiKey.getApiKey());
                cacheableApiKey.setModel(userApiKey.getModel());
                cacheableApiKey.setIsActive(userApiKey.getIsActive());
                cacheableApiKey.setCreatedAt(userApiKey.getCreatedAt());
                cacheableApiKey.setUpdatedAt(userApiKey.getUpdatedAt());

                // 缓存简化对象，1小时
                redisService.set(cacheKey, cacheableApiKey, 3600);
            } catch (Exception e) {
                log.warn("Failed to cache API key: {}", e.getMessage());
            }
            return userApiKey;
        }
        
        return null;
    }

    /**
     * 处理图片生成请求
     * @param userId 用户ID
     * @param request 聊天请求
     * @param outputStream 输出流
     * @param userApiKey 用户API Key
     */
    private void handleImageGeneration(Long userId, ChatRequest request, OutputStream outputStream, UserApiKey userApiKey) throws IOException {
        try {
            log.info("Processing image generation request for user {}", userId);

            // 构建图片生成请求
            SiliconFlowImageRequest imageRequest = siliconFlowImageClient.buildImageRequest(
                    request.getMessage(),
                    request.getImageSize() != null ? request.getImageSize() : "1024x1024",
                    request.getBatchSize() != null ? request.getBatchSize() : 1,
                    request.getGuidanceScale() != null ? request.getGuidanceScale() : 7.5,
                    request.getNumInferenceSteps() != null ? request.getNumInferenceSteps() : 20,
                    request.getImage()
            );

            // 调用图片生成API
            ImageGenerationResponse imageResponse = siliconFlowImageClient.generateImage(userApiKey.getApiKey(), imageRequest);

            // 构建响应消息
            StringBuilder responseBuilder = new StringBuilder();
            responseBuilder.append("已为您生成图片：\n\n");

            if (imageResponse.getImages() != null && !imageResponse.getImages().isEmpty()) {
                for (int i = 0; i < imageResponse.getImages().size(); i++) {
                    String imageUrl = imageResponse.getImages().get(i).getUrl();
                    responseBuilder.append("![生成的图片").append(i + 1).append("](").append(imageUrl).append(")\n\n");
                }
            }

            responseBuilder.append("生成参数：\n");
            responseBuilder.append("- 尺寸：").append(request.getImageSize()).append("\n");
            responseBuilder.append("- 数量：").append(request.getBatchSize()).append("\n");
            responseBuilder.append("- 引导强度：").append(request.getGuidanceScale()).append("\n");
            if (imageResponse.getTimings() != null) {
                responseBuilder.append("- 生成时间：").append(imageResponse.getTimings().getInference()).append("秒\n");
            }

            String response = responseBuilder.toString();

            // 将响应分块发送，模拟流式效果
            String[] words = response.split("(?<=\\p{Punct})|(?=\\p{Punct})|\\s+");
            for (String word : words) {
                if (!word.trim().isEmpty()) {
                    String chunk = "data: " + word + "\n\n";
                    outputStream.write(chunk.getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    Thread.sleep(50); // 模拟流式延迟
                }
            }

            // 发送结束标记
            outputStream.write("data: [DONE]\n\n".getBytes(StandardCharsets.UTF_8));
            outputStream.flush();

        } catch (Exception e) {
            log.error("Error in image generation for user {}: {}", userId, e.getMessage(), e);
            String errorMsg = "data: {\"error\":\"图片生成失败: " + e.getMessage() + "\"}\n\n";
            outputStream.write(errorMsg.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
        }
    }

    /**
     * 处理图片理解请求
     */
    private void handleImageUnderstanding(Long userId, ChatRequest request, OutputStream outputStream, UserApiKey userApiKey) throws IOException {
        try {
            log.info("Processing image understanding request for user {}", userId);

            // 验证图片数据
            if (request.getUploadedImage() == null || request.getUploadedImage().isEmpty()) {
                String errorMsg = "data: 请上传图片\n\n";
                outputStream.write(errorMsg.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                return;
            }

            // 确保使用支持视觉的模型
            String visionModel = "THUDM/GLM-4.1V-9B-Thinking"; // 使用支持视觉的模型

            // 构建硅基流动AI请求（图片理解）
            SiliconFlowRequest siliconFlowRequest = SiliconFlowRequest.builder()
                    .model(visionModel)
                    .temperature(0.8)
                    .topP(0.8)
                    .stream(true)  // 改为true，启用真正的流式
                    .addUserMessageWithImage(request.getMessage(), request.getUploadedImage())
                    .build();

            log.info("Sending streaming image understanding request to SiliconFlow for user {}, model: {}", userId, visionModel);

            // 调用硅基流动AI流式API
            siliconFlowClient.sendStreamRequest(userApiKey.getApiKey(), siliconFlowRequest, outputStream);

        } catch (Exception e) {
            log.error("Image understanding failed for user {}: {}", userId, e.getMessage(), e);
            String errorMessage = "data: 图片理解失败: " + e.getMessage() + "\n\n";
            outputStream.write(errorMessage.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
        }
    }

    /**
     * 掩码API Key用于显示
     * @param apiKey 原始API Key
     * @return 掩码后的API Key
     */
    private String maskApiKey(String apiKey) {
        if (apiKey == null || apiKey.length() < 8) {
            return "****";
        }
        return apiKey.substring(0, 4) + "****" + apiKey.substring(apiKey.length() - 4);
    }
}
